package foundation.web.flow;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Flow {

	private static final Log log = LogFactory.getLog(Flow.class);
	
	private String currentUrl;
	private Stack<FlowStep> steps;
	private int currentId;
	private FlowStep currentStep;
	private Map<String, Object> sessionParameters = new HashMap<String, Object>();


	public Flow(String url) {
		this.currentUrl = url;
		this.steps = new Stack<FlowStep>(); 
		this.currentId=0;
		log.debug("************************************************** Start a new Flow");
	}


	public int push(String nextUrl, FlowStepStateHolder stateHolder) {
		// previos step status
		FlowStep step = new FlowStep(currentUrl, stateHolder);
		log.debug("************************************************** Push a new FlowState :  ");		
		log.debug("************************************************** URL :" + currentUrl);
		steps.push(step);
		currentId= steps.size()-1;
		currentUrl=nextUrl;
		log.debug("**************************************************Now, the Current URL is:" + currentUrl);		
		return currentId;
	}
	

	public FlowStep pop() {
		// get & remove previous step
		FlowStep previousStep =null;
		if(!steps.isEmpty()){
			previousStep = steps.pop();
			currentUrl = previousStep.getUrl();	
			currentId=steps.size()-1;
		}	
		else
			previousStep =this.currentStep;
		return previousStep;
	}
	
	public FlowStep popTo(String urlTo) {
		// get & remove previous step
		FlowStep previousStep = steps.pop();		
		while(!previousStep.getUrl().equals(urlTo)){
			if(steps.size()>0){
				previousStep = steps.pop();	
				currentId=steps.size()-1;				
			}
			else{
				break;
			}					
		}		
		currentUrl = previousStep.getUrl();
		return previousStep;
	}

	public void push(FlowStep step) {
		// previos step status		
		steps.push(step);		
	}
	
	public String getCurrentUrl() {
		return currentUrl;
	}
	
	public Boolean existPop(){
		if(steps!=null && steps.size()>0){
			return true;
		}
		else
			return false;
	}
	
	


	public FlowStep getCurrentStep() {
		return currentStep;
	}


	public void setCurrentStep(FlowStep currentStep) {
		this.currentStep = currentStep;
	}
	
	///############ Handle of session parameters############
	
	public void putAtribute(String key, Object value){
		this.sessionParameters.put(key, value);
	}
	
	public Object getAtribute(String key){
		return this.sessionParameters.get(key);
	}
	
	public Object removeAtribute(String key){
		return this.sessionParameters.remove(key);
	}
	

}
